package com.class05.advice;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

/**
 * @ClassDescription: 1.定义方法存储增强代码
 * 具体定义几个方法，根据插入的位置决定！
 * 2、使用注解配置  指定插入目标方法的位置
 * 前置   @Before
 * 后置   @AfterReturning
 * 异常   @AfterThrowing
 * 最后   @After
 * 环绕   @Around
 * try{
 * 前置
 * 目标方法执行
 * 后置
 * }catch(){
 * 异常
 * }finally{
 * 最后
 * }
 * 3、配置切点表达式[选中插入的方法   切点]
 * <p>
 * 4、补全注解
 * 加入ioc  @Component
 * 配置切面  @Aspect   =  切点  + 增强
 * spring aop重点是配置  ——>jdk  |   cglib
 * <p>
 * 5、开启aspect注解支持
 * @JdkVersion: 17
 * @Author: yxy
 * @Created: 2023/11/2 14:26
 */
//@Component
//@Aspect
//@Order(20)
public class LogAdvice {
    /* todo ：切点表达式
    固定语法    execution(1 2 3 4 5 (6))
    1.访问修饰符
    public/private
    2、方法的返回参数类型
    String int void
    如果不考虑访问修饰符和返回值！这两位整合在一起写  *
    如果要是不考虑，必须有两个都不考虑！不能出现  *  String
    3、包的位置
    1)具体包：
    com.class05.service.impl
    2)单层模糊：
    com.class05.service.*   * 单层模糊
    3)多层模糊:
    com..impl   ..任意层的模糊
    细节：..不能开头
    找所有impl包 com..impl   不能写成..impl   写成：*..impl
    4、类的名称
    具体：CalculatorPureImpl
    模糊：*
    部分模糊：*Impl
    5、方法名  语法和类型一致
    具体：add
    模糊：*
    部分模糊：*d
    6、(6)形参列表
    没有参数:()
    有具体参数:(String)(String,int)
    模糊参数：(..)有没有参数都可以，有多个也可以
    部分模糊：(String...)String后面有没有无所谓
             (... int)最后一个是参数
             (String ... int) 中间模糊
    7、练习：
    1.查询某包某类下，访问修饰符是公有，返回值是int的全部方法
    public int xx.xx.jj.*(..)    public int  *...*.*(..)
    2.查询某包下类中第一个参数是String的方法
    * xx.xx.jj.*(String..)
    3.查询全部包下，无参数的方法！
    * *..*.*()
    4.查询com包下，以int参数类型结尾的方法
    * com..*.*(..int)
    5.查询指定包下，Service开头类的私有返回值int的无参数方法
    private int xx.xx.Service*.*()
    *
    * */

    //    @Before("execution(* ..impl.CalculatorPureImpl.add(..))")
    @Before("com.class05.pointcut.MyPointCut.pc()")
    public void start() {
        System.out.println("LogAdvice方法开始了");
    }

    //    后置
    @AfterReturning(value = "com.class05.pointcut.MyPointCut.pc()", returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("LogAdvice结果：" + result);
    }

    @After("com.class05.pointcut.MyPointCut.pc()")
    public void after() {
        System.out.println("LogAdvice方法结束了");
    }

    @AfterThrowing("com.class05.pointcut.MyPointCut.pc()")
    public void error() {
        System.out.println("方法报错了");
    }
}
